/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package GISPackage;

import java.awt.Color;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.util.Vector;

/**
 *
 * @author Heather
 */

public class Regions
{

  public Vector<Region> regions = new Vector<Region>();
  private static final String polygonStartString = "POLYGON START";
  private static final String polygonEndString = "POLYGON END";

  public Regions()
  {
  }

  public Color getRegionColor(Vector<Integer> region)
  {
    for (Region r : regions)
    {
      if (r.isSameRegion(region))
      {
        return r.regionColor;
      }
    }

    return null;
  }

  public void addRegion(String name, Vector<Integer> regionPolies, File statisticsFile, File altruismFileDirectory, Color regionColor)
  {
    regions.add(new Region(name, regionPolies, statisticsFile, altruismFileDirectory, regionColor));
  }

  // appends information to end
  public void saveToFile(File saveFile)
  {
    System.out.println("saving file");
    try
    {
      FileWriter writer = new FileWriter(saveFile);
      PrintWriter out = new PrintWriter(writer);

      // first write the number of regions == a tidbit of metadata
      out.println(regions.size());

      for (int i = 0; i < regions.size(); i++)
      {
        Region r = regions.get(i);

        // write name
        out.println(r.name);

        // write polygons
        out.println(polygonStartString);
        Vector<Integer> regionPolies = r.polygons;
        for (Integer rp : regionPolies)
        {
          out.println(rp);
        }
        out.println(polygonEndString);

        // write color
        Color c = r.regionColor;
        out.println(c.getRed());
        out.println(c.getGreen());
        out.println(c.getBlue());

        // write statistics file
        out.println(r.statisticsFile.getAbsolutePath());

        // write altruism file directory
        out.println(r.altruismFileDirectory.getAbsolutePath());
      }

      // close file
      writer.close();
      out.close();
      System.out.println("SAVING DONE");
    } catch (IOException exception)
    {
      System.out.println("error in writing social values to file");
    }
  }

  public void loadFromFile(File loadFile) throws IOException
  {

    System.out.println("start loading");
    FileReader reader = new FileReader(loadFile);
    BufferedReader in = new BufferedReader(reader);

    // first line tells us how many regions
    String inputLine = in.readLine();
    int regionNumber = Integer.parseInt(inputLine);
    for (int i = 0; i < regionNumber; i++)
    {
      String name = "";
      Vector<Integer> polygons = new Vector<Integer>();
      File statisticsFile = null;
      File altruismFileDirectory = null;
      Color regionColor = null;

      // read the name
      inputLine = in.readLine();
      name = inputLine;

      // next line is start polygons
      inputLine = in.readLine();
      // read first number
      inputLine = in.readLine();
      while (!inputLine.equals(polygonEndString))
      {
        polygons.add(Integer.parseInt(inputLine));
        inputLine = in.readLine();
      }

      // read the color
      inputLine = in.readLine();
      int red = Integer.parseInt(inputLine);
      inputLine = in.readLine();
      int green = Integer.parseInt(inputLine);
      inputLine = in.readLine();
      int blue = Integer.parseInt(inputLine);
      regionColor = new Color(red, green, blue);

      inputLine = in.readLine();
      statisticsFile = new File(inputLine);
      inputLine = in.readLine();
      altruismFileDirectory = new File(inputLine);

      Region r = new Region(name, polygons, statisticsFile, altruismFileDirectory, regionColor);
      regions.add(r);
    }

    System.out.println("DONE LOADING");
  }

  public void loadStuctureVariables(File loadFile) throws IOException
  {
    // first figure out the max values
    FileReader reader = new FileReader(loadFile);
    BufferedReader in = new BufferedReader(reader);
    // first line is just the labels.  we're being picky, so we can ignore it
    in.readLine();

    String currentLine = in.readLine();

    int maxLegitimacy = Integer.MIN_VALUE;
    int maxInstability = Integer.MIN_VALUE;
    int maxFragility = Integer.MIN_VALUE;
    int maxPopulation = Integer.MIN_VALUE;
    double maxUrbanPopulation = Double.MIN_VALUE;
    int maxLandArea = Integer.MIN_VALUE;
    double maxLifeExpectancy = Double.MIN_VALUE;
    double maxInfancyMortalityRate = Double.MIN_VALUE;
    double maxLiteracy = Double.MIN_VALUE;
    double maxEducation = Double.MIN_VALUE;
    double maxPoverty = Double.MIN_VALUE;
    double maxGrowthGDP = Double.MIN_VALUE;

    while (currentLine != null)
    {
      StringTokenizer tokenizer = new StringTokenizer(currentLine, ",");
      int numberOfFactorsForI = 0;
      int numberOfFactorsForC = 0;
      int numberOfFactorsForLambda = 0;
      int numberOfFactorsForF = 0;

      String name = tokenizer.nextToken();
      //System.out.println(name);

      String averageIncomeString = tokenizer.nextToken();
      int averageIncome = 0;
      if (!averageIncomeString.equals("NA"))
      {
        averageIncome = (int) Double.parseDouble(averageIncomeString);
      }
      //System.out.println("AVE INCOME: " + averageIncomeString);

      String percentGrowthGDPString = tokenizer.nextToken();
      double percentageGrowthGDP = 0;
      if (!percentGrowthGDPString.equals("NA"))
      {
        percentageGrowthGDP = Double.parseDouble(percentGrowthGDPString);
        numberOfFactorsForF++;

        if (percentageGrowthGDP > maxGrowthGDP)
          maxGrowthGDP = percentageGrowthGDP;
      }
      //System.out.println("percentGDP: " + percentGrowthGDPString);

      String percentPovertyString = tokenizer.nextToken();
      double percentPoverty = 0;
      if (!percentPovertyString.equals("NA"))
      {
        percentPoverty = Double.parseDouble(percentPovertyString);
        numberOfFactorsForLambda++;

        if (percentPoverty > maxPoverty)
          maxPoverty = percentPoverty;
      }
      //System.out.println("percentPovertyString: " + percentPovertyString);

      String lifeExpectancyString = tokenizer.nextToken();
      double lifeExpectancy = 0;
      if (!lifeExpectancyString.equals("NA"))
      {
        lifeExpectancy = Double.parseDouble(lifeExpectancyString);
        numberOfFactorsForLambda++;

        if (lifeExpectancy > maxLifeExpectancy)
          maxLifeExpectancy = lifeExpectancy;
      }
      //System.out.println(lifeExpectancyString);

      String infancyMortalityRateString = tokenizer.nextToken();
      double infancyMortalityRate = 0;
      if (!infancyMortalityRateString.equals("NA"))
      {
        infancyMortalityRate = Double.parseDouble(infancyMortalityRateString);
        numberOfFactorsForLambda++;

        if (infancyMortalityRate > maxInfancyMortalityRate)
          maxInfancyMortalityRate = infancyMortalityRate;
      }
      //System.out.println(infancyMortalityRateString);

      String percentLiteracyString = tokenizer.nextToken();
      double percentLiteracy = 0;
      if (!percentLiteracyString.equals("NA"))
      {
        percentLiteracy = Double.parseDouble(percentLiteracyString);
        numberOfFactorsForLambda++;

        if (percentLiteracy > maxLiteracy)
          maxLiteracy = percentLiteracy;
      }
      //System.out.println(percentLiteracyString);

      String educationString = tokenizer.nextToken();
      double education = 0;
      if (!educationString.equals("NA"))
      {
        education = Double.parseDouble(educationString);
        numberOfFactorsForLambda++;

        if (education > maxEducation)
          maxEducation = education;
      }
      //System.out.println(educationString);

      String regimeTypeString = tokenizer.nextToken();
      int regimeType = 0;
      if (!regimeTypeString.equals("NA"))
      {
        regimeType = (int) Double.parseDouble(regimeTypeString);
        numberOfFactorsForI++;
        
      }
      //System.out.println(regimeTypeString);

      String regimeInstitutionString = tokenizer.nextToken();
      int regimeInstitution = 0;
      if (!regimeInstitutionString.equals("NA"))
      {
        regimeInstitution = (int) Double.parseDouble(regimeInstitutionString);
        numberOfFactorsForI++;
      }
      //System.out.println(regimeInstitutionString);

      String regimeLegitimacyString = tokenizer.nextToken();
      int regimeLegitimacy = 0;
      if (!regimeLegitimacyString.equals("NA"))
      {
        regimeLegitimacy = (int) Double.parseDouble(regimeLegitimacyString);
        numberOfFactorsForI++;

        if (regimeLegitimacy > maxLegitimacy)
          maxLegitimacy = regimeLegitimacy;
      }
      //System.out.println(regimeLegitimacyString);

      String regimeInstabilityString = tokenizer.nextToken();
      int regimeInstability = 0;
      if (!regimeInstabilityString.equals("NA"))
      {
        regimeInstability = (int) Double.parseDouble(regimeInstabilityString);
        numberOfFactorsForI++;

        if (regimeInstability > maxInstability)
          maxInstability = regimeInstability;
      }
      //System.out.println(regimeInstabilityString);

      String stateFragilityString = tokenizer.nextToken();
      int stateFragility = 0;
      if (!stateFragilityString.equals("NA"))
      {
        stateFragility = (int) Double.parseDouble(stateFragilityString);
        numberOfFactorsForI++;

        if (stateFragility > maxFragility)
          maxFragility = stateFragility;
      }
      //System.out.println(stateFragilityString);

      String populationString = tokenizer.nextToken();
      int population = 0;
      if (!populationString.equals("NA"))
      {
        population = (int) Double.parseDouble(populationString);
        numberOfFactorsForC++;

        if (population > maxPopulation)
          maxPopulation = population;
      }
      //System.out.println(populationString);

      // CHECK THIS IN INPUT FILE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      //System.out.println("CAUTION: POPULATION HAD BETTER NOT BE IN MILLIONS");
      String percentUrbanPopulationString = tokenizer.nextToken();
      double percentUrbanPopulation = 0;
      if (!percentUrbanPopulationString.equals("NA"))
      {
        percentUrbanPopulation = Double.parseDouble(percentUrbanPopulationString);
        numberOfFactorsForC++;

        if (percentUrbanPopulation > maxUrbanPopulation)
          maxUrbanPopulation = percentUrbanPopulation;
      }
      //System.out.println(percentUrbanPopulationString);

      String landAreaString = tokenizer.nextToken();
      int landArea = 0;
      if (!landAreaString.equals("NA"))
      {
        landArea = (int) Double.parseDouble(landAreaString);
        numberOfFactorsForC++;

        if (landArea > maxLandArea)
          maxLandArea = landArea;
      }
      //System.out.println("this is the LAND AREA: " + landAreaString);

      String mountainousTerrainIntString = tokenizer.nextToken();
      int mountainousTerrainInt = 0;
      if (!mountainousTerrainIntString.equals("NA"))
      {
        mountainousTerrainInt = (int) Double.parseDouble(mountainousTerrainIntString);
        numberOfFactorsForC++;
      }
      //System.out.println(mountainousTerrainIntString);

      boolean mountainousTerrain = false;
      // correct anything that needs corrections
      if (mountainousTerrainInt > 0)
      {
        mountainousTerrain = true;
      }

      // find the correct region
      Region loadRegion = null;
      for (Region r : regions)
      {
        if (name.equals(r.name))
        {
          loadRegion = r;
        }
      }

      // TEST CODE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      if (loadRegion == null)
      {
        Vector<Integer> polygons = new Vector<Integer>();
        polygons.add(1);
        polygons.add(2);
        polygons.add(3);

        File statisticsFile = new File("c:/CCPV Data/all structure variables.csv");
        File altruismFileDirectory = new File("c:/CCPV Data/all structure variables.csv");
        Color regionColor = new Color(1, 2, 3);

        loadRegion = new Region(name, polygons, statisticsFile, altruismFileDirectory, regionColor);
        regions.add(loadRegion);
      }

      if (loadRegion != null)
      {
        loadRegion.setStructuralVariables(averageIncome,
                percentageGrowthGDP,
                percentPoverty,
                lifeExpectancy,
                infancyMortalityRate,
                percentLiteracy,
                education,
                regimeType,
                regimeInstitution,
                regimeLegitimacy,
                regimeInstability,
                stateFragility,
                population,
                percentUrbanPopulation,
                landArea,
                mountainousTerrain,
                numberOfFactorsForI,
                numberOfFactorsForC,
                numberOfFactorsForLambda,
                numberOfFactorsForF);
      }
      else
      {
        System.out.println("WARNING: File contains region that is unknown. " + name + " was NOT loaded.");
      }

      // read the next line
      currentLine = in.readLine();
    }

    // set min / max
    Region.setMaxValues(maxLegitimacy,
            maxInstability,
            maxFragility,
            maxPopulation,
            maxUrbanPopulation,
            maxLandArea,
            maxLifeExpectancy,
            maxInfancyMortalityRate,
            maxLiteracy,
            maxEducation,
            maxPoverty,
            maxGrowthGDP);
    for (Region r : regions)
    {
      r.calculateAndSetAllStructuralVariables();
    }

    in.close();
    reader.close();
  }

  public String toString()
  {
    String ret = "";

    int i = 0;
    for (Region r : regions)
    {
      i++;
      ret += "Region " + i + ": " + "\n";
      ret += r.toString() + "\n";
    }

    return ret;
  }
}
